顔認証のクラウドサービスMercury Cloudで遊んでみる – 顔検知 –
Mercury Cloudという顔認証のサービスを触る機会があったのでご紹介します。
顔認証のユースケースとしては、 オンラインサービスの本人確認、チケットレス入場(スタジアムやイベント会場など)、鍵解錠などが挙げられます。
Mercury Cloudは、既存のサービスでも簡単に顔認証を追加できるようなAPIを提供しているサービスです。 APIを実行するロジックは自身で追加しないといけません。
特徴として
- 高速で顔を認識
- 高精度な認証(マスク着用時も高い認証を誇る)
- 2000万人の顔データ登録が可能
- 顔の特徴から年齢や性別などの属性の識別が可能
といったものが挙げられています。
用意されているAPIですが、大きく分けると
- 顔検知
- 画像内の顔を検出し顔枠に外接する長方形の座標を返します
- 顔比較
- 2つの画像の中にあるそれぞれ最大の顔を検出し、これら2つの顔が同じ人物であるかどうかを確認
- 顔検索
- 特徴データベースに登録されているすべての顔特徴の中からアップロードした画像から検出された顔を検索し、最も近い結果を返します
があります。
本記事では顔検知を試していきたいと思います。
使ってみる
base uri: https://<<domain.com>>/openapi/face/v1
domain.com っは、サービス地域によって変わってきます。サービス開始時の連絡メールにこのドメイン部分は記載されています。
認証について
全てのAPIでクライアントの検証のためAPI認証トークンが必須となっています。
各APIを呼び出す際に、2つのヘッダー(x-dateとAuthorization)が必要です。それらが含まれていない場合、401のHTTPエラーコードが表示されます。
x-date
RFC-7231形式でのUTC日付と時刻の形式を使用します
Fri, 09 Jul 2021 01:51:02 GMT
Authorization
指定されたAPIパス、HTTPメソッド、アプリID、アクセスキー、およびシークレットキーに基づいて生成されます。特徴DBに関連する一部のAPIではDB IDも必要で、 以下のフォーマットに従う必要があります。
hmac username="{Access_key}", algorithm="hmac-sha256", headers="x-date request-line", signature="{Signature}"
Authorizationヘッダーの作成 に作成手順が詳しく記載されています。
アプリID、アクセスキー、およびシークレットキーはサービス開始時の連絡時に記載されているものを使用します。
これらの情報は安全な箇所に保管し、他人に開示してはいけない情報となっています。
ヘッダー作成ツールサンプル がドキュメントに用意されていますので、これを利用して作成することができます。
サンプル実行例)
画像について
Mercury Cloud APIはHTTPリクエストで、base64でエンコードされたバイナリを使用して画像データを送信します。
例)
def base64_encode_file(file_path): handle = open(file_path, "rb") raw_bytes = handle.read() handle.close() return base64.b64encode(raw_bytes).decode("utf-8")
- 画像のフォーマットは、JPG、PNG、BMP、TIFF、またはGIF
- 画像のファイルサイズは、8MB未満
- 有効な顔サイズは、32✕32ピクセル以上
- バッチアップロードがサポートされている顔検知APIと顔特徴追加APIでは、1回のAPI呼び出しでの画像の数量は16以下
以上の基準を守る必要があります。
基本的に画像の画質が高いほど精度が高くなりますが、ファイルサイズが大きいほどAPIの呼び出し時間が長くなります。
APIを呼び出す前に、高品質・正面・鮮明な画像を、有効な顔サイズが200x200ピクセル以上を確保しながら、画像をトリミングして200KB未満に圧縮すること
が推奨されていました。
顔検知API
URL
https://{domain}/openapi/face/v1/{app_id}/detect
Parameters
- x-date (必須)
- API認証時使用されるRFC-7231フォーマットのUTC日時文字列のヘッダーパラメータ
- 例:
Wed, 03 Mar 2021 02:11:37 GMT
- app_id (必須)
- テナントの下のアプリケーションIDを指定するURLパラメータ
Request body
指定された画像のバイナリデータ(base64でエンコード)
{ "images": [ { "data": "/9j/4AAQSk...ZJRgABAQEA" } ] }
実行例
認証ヘッダーの作成、画像のbase64でエンコードを行った後、顔検知APIのURLにパラメータをつけて実行します。
アクセス例)
curl -X 'POST' 'https://<<domain>>/openapi/face/v1/<<app_id>>/detect' -H 'accept: application/json' -H 'x-date: <<RFC-7231フォーマットのUTC日時>>' -H 'Authorization: hmac username="<<api_key>>", algorithm="hmac-sha256", headers="x-date request-line", signature="<<signature>>"' -H 'Content-Type: application/json' -d '{ "images": [ { "data": "/9j/4QAYRXhpZgAASUkqAAgAAAAAAAAAAAAAAP/~~~~~~~~~~sABFEdIMSMMQhNS/p19B6v0H+C/ouXGX6HrA0R" } ] }'
画像1
- レスポンス
{ "trace_id": "f035eca5057ff86f81407e6fa494abed", "results": [ { "code": 80303, "message": "No face found.", "internal_code": 303 } ], "batches": [ { "faces": [] } ] }
顔が検知できなかったといういうレスポンスが返ってきた例です
画像2
- レスポンス
{ "trace_id": "af32b826835ff2d152609c03e5e77920", "results": [ { "code": 80303, "message": "No face found.", "internal_code": 303 } ], "batches": [ { "faces": [] } ] }
イラストだと顔が検知できないようです
画像3
- レスポンス
{ "trace_id": "a29ceb0182508c5c012fb209c62c1b57", "results": [ { "code": 0, "message": "Success.", "internal_code": 0 } ], "batches": [ { "faces": [ { "quality": 0.99826276, "rectangle": { "top": 220, "left": 162, "width": 203, "height": 196 }, "angle": { "yaw": 17.226185, "pitch": 8.400441, "roll": 15.522398 }, "landmarks": [ { "x": 163, "y": 277 }, { "x": 167, "y": 289 }, ~~~~~~~, { "x": 269, "y": 255 } ], "attributes": { "age_lower_limit": { "type": 0, "category": "age_lower_limit", "value": 23 }, "age_up_limit": { "type": 0, "category": "age_up_limit", "value": 33 }, "cap_style": { "type": 2, "category": "HAT_STYLE_TYPE_NONE", "value": 0.999972 }, "gender_code": { "type": 2, "category": "MALE", "value": 0.999675 }, "glass_style": { "type": 2, "category": "GLASSES_STYLE_TYPE_NONE", "value": 0.9972076 }, "mustache_style": { "type": 2, "category": "MUSTACHE_STYLE_TYPE_NONE", "value": 0.97730595 }, "respirator_color": { "type": 2, "category": "COLOR_TYPE_NONE", "value": 0.99573535 }, "st_age": { "type": 2, "category": "ST_ADULT", "value": 1 }, "st_expression": { "type": 2, "category": "ST_CALM", "value": 0.99880713 }, "st_helmet_style": { "type": 2, "category": "ST_HELMET_STYLE_TYPE_NONE", "value": 0.9993663 }, "st_respirator": { "type": 0, "category": "", "value": 0 } }, "rotated": 1 } ] } ] }
顔検知が成功すると、上記のようなレスポンスが返ってきます。
st_ageがST_ADULT
なので大人、gender_code
がMALE
なので男性, respirator_color
がCOLOR_TYPE_NONE
なのでマスク着用無 と推測されたようです。
あってますね、すごい。
属性に関して詳しくは
を参照。
画像4
- レスポンス
{ "trace_id": "f97f4e32e12b0c9d2df3f4c8f6f4ccb1", "results": [ { "code": 0, "message": "Success.", "internal_code": 0 } ], "batches": [ { "faces": [ { "quality": 0.9982797, "rectangle": { "top": 150, "left": 181, "width": 130, "height": 136 }, "angle": { "yaw": 18.2098, "pitch": 7.520368, "roll": -15.592735 }, "landmarks": [ { "x": 198, "y": 162 }, ~~~~~~~~~~~ { "x": 262, "y": 178 } ], "attributes": { "age_lower_limit": { "type": 0, "category": "age_lower_limit", "value": 27 }, "age_up_limit": { "type": 0, "category": "age_up_limit", "value": 37 }, "cap_style": { "type": 2, "category": "HAT_STYLE_TYPE_NONE", "value": 0.98707956 }, "gender_code": { "type": 2, "category": "MALE", "value": 0.99992156 }, "glass_style": { "type": 2, "category": "GLASSES_STYLE_TYPE_NONE", "value": 0.9942698 }, "mustache_style": { "type": 2, "category": "MUSTACHE_STYLE_TYPE_NONE", "value": 0.67222404 }, "respirator_color": { "type": 2, "category": "COLOR_TYPE_OTHER", "value": 0.9999087 }, "st_age": { "type": 2, "category": "ST_ADULT", "value": 1 }, "st_expression": { "type": 2, "category": "ST_HAPPY", "value": 0.85142446 }, "st_helmet_style": { "type": 2, "category": "ST_HELMET_STYLE_TYPE_NONE", "value": 0.99641335 }, "st_respirator": { "type": 0, "category": "", "value": 0 } }, "rotated": 1 } ] } ] }
respirator_color
が COLOR_TYPE_OTHER
となっているのでマスク着用有
と判定されています。
あってますね。
画像5
- レスポンス
{ "trace_id": "4a731fb6205477d95f4493594fc542e7", "results": [ { "code": 80303, "message": "No face found.", "internal_code": 303 } ], "batches": [ { "faces": [] } ] }
顔が小さいためか、顔検知はできませんでした。
画像6
- レスポンス
{ "trace_id": "22a81df7f812bf6b99d0593f5ce1f19d", "results": [ { "code": 0, "message": "Success.", "internal_code": 0 } ], "batches": [ { "faces": [ { "quality": 0.9965526, "rectangle": { "top": 292, "left": 45, "width": 123, "height": 142 }, "angle": { "yaw": 59.729923, "pitch": 4.07797, "roll": 7.824665 }, "landmarks": [ { "x": 46, "y": 322 }, ~~~~~~~ { "x": 79, "y": 322 } ], "attributes": { "age_lower_limit": { "type": 0, "category": "age_lower_limit", "value": 16 }, "age_up_limit": { "type": 0, "category": "age_up_limit", "value": 26 }, "cap_style": { "type": 2, "category": "HAT_STYLE_TYPE_NONE", "value": 0.99567693 }, "gender_code": { "type": 2, "category": "FEMALE", "value": 0.9466953 }, "glass_style": { "type": 2, "category": "GLASSES_STYLE_TYPE_NONE", "value": 0.9986252 }, "mustache_style": { "type": 2, "category": "MUSTACHE_STYLE_TYPE_NONE", "value": 0.9887771 }, "respirator_color": { "type": 2, "category": "COLOR_TYPE_NONE", "value": 0.9993965 }, "st_age": { "type": 2, "category": "ST_ADULT", "value": 1 }, "st_expression": { "type": 2, "category": "ST_CALM", "value": 0.7430104 }, "st_helmet_style": { "type": 2, "category": "ST_HELMET_STYLE_TYPE_NONE", "value": 0.9973989 }, "st_respirator": { "type": 0, "category": "", "value": 0 } }, "rotated": 1 }, { "quality": 0.9761087, "rectangle": { "top": 341, "left": 847, "width": 75, "height": 82 }, ~~~~~ }, { "quality": 0.96427304, ~~~~~~~~~ }, { "quality": 0.9879387, ~~~~~~ } ] } ] }
複数の顔を検知することも可能でした。
faces
に検知した複数の顔の情報が格納されています。
st_expression
には ST_CALM
、ST_HAPPY
などで分類されていました。
最後に
顔認証クラウドサービスMercury Cloudの顔検知APIを使ってみました。
6枚の画像でしか試していませんが、全て顔の検知はできていましたね。 精度が高いと評価されているのもうなづけます。
今回は検知だけでしたが、次回は検知したデータを使い顔の比較を行ってみたいと思います。